package com.mes.common.rule;

import java.io.File;
import java.lang.reflect.Method;
import java.util.List;

import org.drools.KnowledgeBase;
import org.drools.KnowledgeBaseFactory;
import org.drools.builder.KnowledgeBuilder;
import org.drools.builder.KnowledgeBuilderFactory;
import org.drools.builder.ResourceType;
import org.drools.io.ResourceFactory;
import org.drools.runtime.StatefulKnowledgeSession;
import org.drools.runtime.rule.FactHandle;

import com.mes.common.usermanagement.MMPath;

import com.mes.common.spring.SpringUtils;

/**
 * AbstractKnowledgeApplication
 * 
 * @author nk
 */
public abstract class AbstractKnowledgeApplication
{
	private StatefulKnowledgeSession ksession;
	private KnowledgeBase knowledgeBase;

	public StatefulKnowledgeSession getKsession()
	{
		return ksession;
	}

	public void setKsession(StatefulKnowledgeSession ksession)
	{
		this.ksession = ksession;
	}

	public KnowledgeBase getKnowledgeBase()
	{
		return knowledgeBase;
	}

	public void setKnowledgeBase(KnowledgeBase knowledgeBase)
	{
		this.knowledgeBase = knowledgeBase;
	}

	public AbstractKnowledgeApplication()
	{

	}

	/**
	 * ���췽�������ù����
	 * 
	 * @param knowledgeBase
	 */
	public AbstractKnowledgeApplication(KnowledgeBase knowledgeBase)
	{
		this.setKnowledgeBase(knowledgeBase);
		this.setKsession(knowledgeBase.newStatefulKnowledgeSession());

		// ����ȫ�ֱ����ļ���
		this.globalSetting();
	}

	protected abstract void globalSetting();

	public void reload(KnowledgeBase knowledgeBase) throws Exception
	{
		this.knowledgeBase = knowledgeBase;

		this.setKsession(knowledgeBase.newStatefulKnowledgeSession());
		this.globalSetting();
	}

	public void reload(List<String> beanList, String drlFileName)
			throws Exception
	{
		KnowledgeBuilder kbuilder = KnowledgeBuilderFactory
				.newKnowledgeBuilder();

		String ruleFilePath = MMPath.getMMHome() + "droolsrules/";
		String ruleFileName = drlFileName;
		File file = new File(ruleFilePath + ruleFileName);

		kbuilder.add(ResourceFactory.newFileResource(file), ResourceType.DRL);
		knowledgeBase = KnowledgeBaseFactory.newKnowledgeBase();
		knowledgeBase.addKnowledgePackages(kbuilder.getKnowledgePackages());

		for (String beanId : beanList)
		{
			Object object = SpringUtils.getBean(beanId);

			Method reloadMethod = object.getClass().getDeclaredMethod("reload",
					new Class[] { KnowledgeBase.class });

			reloadMethod.invoke(object, new Object[] { knowledgeBase });
		}
	}

	/**
	 * ��ӻ��߸�����ʵ
	 * 
	 * @param object �����µ���ʵ
	 */
	protected void insertOrUpdate(Object object)
	{
		if (object == null)
		{
			return;
		}

		// ksession.insert(object);
		FactHandle factHandle = ksession.getFactHandle(object);
		if (factHandle == null)
		{
			ksession.insert(object);
		}
		else
		{
			ksession.update(factHandle, object);
		}
	}

	/**
	 * �ڹ����ռ��������ʵ
	 * 
	 * @param object ���������ʵ
	 */
	protected void delete(Object object)
	{
		if (object == null)
		{
			return;
		}

		FactHandle factHandle = ksession.getFactHandle(object);
		if (factHandle == null)
		{
			return;
		}
		else
		{
			ksession.retract(factHandle);
		}
	}

	/**
	 * �ڹ����ռ��������ʵ����
	 * 
	 * @param list ���������ʵ����
	 */
	@SuppressWarnings("unchecked")
	protected void delete(List list)
	{
		if (list == null)
		{
			return;
		}

		for (Object object : list)
		{
			FactHandle factHandle = ksession.getFactHandle(object);
			if (factHandle == null)
			{
				return;
			}
			else
			{
				ksession.retract(factHandle);
			}
		}
	}
}
